package redis

import (
	"errors"
	"fmt"
	"math"
	"strconv"
	"time"

	"go.uber.org/zap"

	"github.com/go-redis/redis"
)

const (
	OneWeekInSeconds         = 7 * 24 * 3600
	VoteScore        float64 = 432
	PostPerAge               = 20
)

var (
	ErrorVoteTimeExpire = errors.New("投票时间已过")
	ErrVoteRepested     = errors.New("不能重复投票")
)

func VoteFormPost(userID, postID string, value float64) (err error) {
	zap.L().Error("redis VoteFormPost",
		zap.String("userId:", userID),
		zap.String("postId:", postID),
		zap.Float64("value:", value))

	postTime := client.ZScore(getRedisKey(KeyPostTimeZSet), postID).Val()
	if float64(time.Now().Unix())-postTime > OneWeekInSeconds { // Unix()时间戳
		return ErrorVoteTimeExpire
	}
	key := KeyPostVotedZSetPrefix + postID
	ov := client.ZScore(getRedisKey(key), userID).Val()
	if value == ov {
		return ErrVoteRepested
	}
	var op float64
	if value > 0 {
		op = 1
	} else {
		op = -1
	}
	pipline := client.Pipeline()
	diff := math.Abs(ov - value)
	fmt.Println("ov:", ov)
	fmt.Println("value:", value)
	fmt.Println("diff:", diff)
	fmt.Println("op:", op)
	pipline.ZIncrBy(getRedisKey(KeyPostScoreZSet), op*diff*VoteScore, postID)

	if value == 0 {
		pipline.ZRem(getRedisKey(key), postID)
	} else {
		pipline.ZAdd(getRedisKey(key), redis.Z{
			Score:  value,
			Member: userID,
		})
	}
	_, err = pipline.Exec()
	return
}

// 记录该帖子保存数据同时 也写入redis
func CreateInsertPost(postId, communityId int64) (err error) {
	pipline := client.Pipeline()
	pipline.ZAdd(getRedisKey(KeyPostTimeZSet), redis.Z{
		Score:  float64(time.Now().Unix()),
		Member: postId,
	})
	communityKey := getRedisKey(KeyCommunityPostSetPrefix) + strconv.Itoa(int(communityId))
	pipline.SAdd(communityKey, postId)
	_, err = pipline.Exec()
	return
}
